package com.atguigu.cms.main;

import com.atguigu.cms.javabean.Customer;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 学习一下反射机制
 */
public class TestFanShe {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//        System.out.println("--------------以下是不使用反射的操作--------------");
//        Customer customer = new Customer();
//        customer.setAge(21);
//        customer.setName("wxj");
//        customer.setPhone("1322432");
//        customer.setGender("nv");
//        customer.setSalary(122222);
//        customer.setId(1);
//        System.out.println(customer.toString());

        System.out.println("--------------以下是使用反射的操作--------------");
        System.out.println("CLASS对象的基本方法");
        Class clazz = Class.forName("com.atguigu.cms.javabean.Customer");
        System.out.println(clazz.getName());
        System.out.println(clazz.getSimpleName());
        System.out.println(clazz.getSuperclass());
        System.out.println(Arrays.toString(clazz.getInterfaces()));


        System.out.println();
        System.out.println("如果是私有的方法或者属性，需要用Declared");
        //如果是私有的方法或者属性，需要用Declared

        //获得所有的构造方法
        System.out.println("获得所有的构造方法");
        Constructor[] constructors = clazz.getDeclaredConstructors();
        System.out.println(constructors.length);

        System.out.println();

        //获取属性
        System.out.println("获取属性");
        Field[] fields = clazz.getDeclaredFields();
        System.out.println("fields.length   "+fields.length);
        for (Field f : fields) {
            System.out.println(f);
        }
        System.out.println();
        Field id = clazz.getDeclaredField("id");
        System.out.println(id);

        System.out.println("获取方法");
        Method[] ms = clazz.getDeclaredMethods();
        for (Method m : ms) {
            System.out.println(m);
        }
        System.out.println();

        //使用Class的方法创建目标实例对象
        System.out.println("使用Class的方法创建对象");
        Object customer = clazz.newInstance();//属性需要有初值
//        Object c = clazz.getConstructor().newInstance(); //Class com.atguigu.cms.main.TestFanShe can not access a member of class com.atguigu.cms.javabean.Customer with modifiers "private"
        System.out.println(customer.toString());

        System.out.println();
        System.out.println("使用反射操作属性");
        //因为id是私有属性，需要打破私有属性的限制，设置setAccessible为true
        id.setAccessible(true);
        //给属性赋值
        id.set(customer,3);
        //输出给属性
        System.out.println("customer.toString():"+customer.toString());
        System.out.println("id.get(customer):"+id.get(customer));

        System.out.println();

        System.out.println("使用反射执行方法");
        Method getName = clazz.getDeclaredMethod("getName");
        Object invoke = getName.invoke(customer);
        System.out.println(invoke);

        System.out.println();
    }

}
